<template>
    <div class="xpage">
        <div class="left_obj">
            <div v-for="item in deviceTypeList" :key="item.label" draggable="true"
                @dragstart="handleDragStart($event, item)" class="draggable-item">
                <img style="width:50px;height:50px" :src="type_icon_map[item.type]" alt="">
                <div>
                    {{ item.label }}
                </div>
            </div>

            <div class="draggable-item" @click="export_svg()">
                toJSON() 导出
            </div>
        </div>

        <div ref="container" id="container" class="my_container" @dragover="handleDragOver" @drop="handleDrop"></div>



        <a-modal v-model:visible="modalVisible" :title="`编辑设备`" @ok="handleModalOk" @cancel="handleModalCancel">
            <!-- 设备名称选择 -->

            <div class="update_item">
                <span> 请输入设备名称: </span>

                <a-input style="width:160px" @change="change_device" v-model:value="deviceForm.deviceName"
                    class="val_item">

                </a-input>
            </div>
            <div class="update_item">

                <span style="color:#fff">请选择需要绑定的设备: </span>
                <a-select style="width:160px" :field-names="{ label: 'label', value: 'deviceNo' }" class="val_item"
                    v-model:value="deviceForm.deviceNo" :options="device_list" placeholder="请选择设备">
                </a-select>
            </div>
            <div class="update_item">
                <span style="color:#fff">请选择需要绑定的点位: </span>
                <a-select style="width:160px" :field-names="{ label: 'label', value: 'tagcode' }"
                    @change="change_tagcode" class="val_item" mode="multiple" placeholder="请选择参数"
                    :options="tagcode_ptions" />
            </div>
        </a-modal>



    </div>
</template>

<script setup>
import { onMounted, ref, reactive, watch, onBeforeUnmount } from 'vue';
import { Graph } from '@antv/x6';

// 默认图片URL（使用AntV的示例图片）
const DEFAULT_IMAGE = 'https://gw.alipayobjects.com/zos/bmw-prod/c55d7ae1-8d20-4585-bd8f-ca23653a4489.svg';

const container = ref(null);
const graph = ref(null);
const draggedItem = ref(null);


// 图标导入
import pcsIcon from '@/assets/svg_icon/icon01.svg';
import bmsIcon from '@/assets/svg_icon/icon02.svg';
import meterIcon from '@/assets/svg_icon/icon03.svg';

import pcspng from '@/assets/png/image1.png';
import bmspng from '@/assets/png/image2.png';
import meterpng from '@/assets/png/image3.png';
import { Modal } from 'ant-design-vue';


let pcsIcon_64 = '';
let bmsIcon_64 = ''
let meterIcon_64 = ''

async function convertImageToBase64(file) {

    let res = '';
    await new Promise((resolve, reject) => {
        // 创建FileReader对象
        const reader = new FileReader();

        // 定义文件读取完成后的处理函数
        reader.onload = function (e) {
            // e.target.result包含了图片的Base64编码字符串
            res = resolve(e.target.result);

            console.log("res", res)
        };

        // 定义文件读取发生错误的处理函数
        reader.onerror = function (e) {
            reject(e);
        };

        // 读取文件并转换为DataURL
        reader.readAsDataURL(file);

    });

    return res;
}

let modalVisible = ref(false);
let selectedDevice = ref(null);



let deviceForm = ref({
    deviceName: '',
    deviceNo: '',
    deviceTagcode: [
        {
            tagCode: "P",
            unit: 'kW',
            defaultValue: ''
        }
    ]
});


let connectingState = reactive({
    isConnecting: false,
    sourceNode: null,
    edge: null
});

// let ports = {
//   groups: {
//     top: { position: 'top', attrs: { circle: { r: 4, magnet: true, stroke: '#5F95FF', strokeWidth: 1, fill: '#fff', style: { visibility: 'hidden' } } } },
//     right: { position: 'right', attrs: { circle: { r: 4, magnet: true, stroke: '#5F95FF', strokeWidth: 1, fill: '#fff', style: { visibility: 'hidden' } } } },
//     bottom: { position: 'bottom', attrs: { circle: { r: 4, magnet: true, stroke: '#5F95FF', strokeWidth: 1, fill: '#fff', style: { visibility: 'hidden' } } } },
//     left: { position: 'left', attrs: { circle: { r: 4, magnet: true, stroke: '#5F95FF', strokeWidth: 1, fill: '#fff', style: { visibility: 'hidden' } } } },
//   },
//   items: [
//     { group: 'top' },
//     { group: 'right' },
//     { group: 'bottom' },
//     { group: 'left' },
//   ],
// };

// 设备图标映射
// let type_icon_map = {
//     pcs: pcsIcon,
//     bms: bmsIcon,
//     meter: meterIcon,
// };

// 设备图标映射
let type_icon_map = {
    27: pcsIcon_64,
    28: bmsIcon_64,
    1: meterIcon_64,
};

// 设备列表
let deviceTypeList = [
    { label: 'PCS', type: '27' },
    { label: 'BMS', type: '28' },
    { label: '电表1', type: '1' }
];


// 端口配置
let ports = {
    groups: {
        top: { position: 'top', attrs: { circle: { r: 4, magnet: true, stroke: '#5F95FF', strokeWidth: 1, fill: '#fff', style: { visibility: 'hidden' } } } },
        right: { position: 'right', attrs: { circle: { r: 4, magnet: true, stroke: '#5F95FF', strokeWidth: 1, fill: '#fff', style: { visibility: 'hidden' } } } },
        bottom: { position: 'bottom', attrs: { circle: { r: 4, magnet: true, stroke: '#5F95FF', strokeWidth: 1, fill: '#fff', style: { visibility: 'hidden' } } } },
        left: { position: 'left', attrs: { circle: { r: 4, magnet: true, stroke: '#5F95FF', strokeWidth: 1, fill: '#fff', style: { visibility: 'hidden' } } } },
    },
    items: [
        { group: 'top' },
        { group: 'right' },
        { group: 'bottom' },
        { group: 'left' },
    ],
};

// 设备参数配置
let deviceParamsConfig = {
    meter: [
        { key: 'power', label: '功率', unit: 'kW', defaultValue: '10' },
        { key: 'voltage', label: '电压', unit: 'V', defaultValue: '220' }
    ],
    pcs: [
        { key: 'capacity', label: '容量', unit: 'kWh', defaultValue: '50' },
        { key: 'efficiency', label: '效率', unit: '%', defaultValue: '95' }
    ],
    bms: [
        { key: 'cells', label: '电池数量', unit: '节', defaultValue: '16' },
        { key: 'temperature', label: '温度', unit: '°C', defaultValue: '25' }
    ]
};


// 注册自定义节点
// Graph.registerNode('device-node', {
//     inherit: 'rect',
//     markup: [
//         { tagName: 'rect', selector: 'body' },
//         { tagName: 'image', selector: 'image' },
//         { tagName: 'text', selector: 'text' },
//     ],
//     attrs: {
//         body: {
//             stroke: '#5F95FF',
//             strokeWidth: 1,
//             fill: '#EFF4FF',
//             rx: 6, // 圆角
//             ry: 6
//         },
//         image: {
//             'xlink:href': DEFAULT_IMAGE,
//             width: 40,
//             height: 40,
//             x: 10,
//             y: 10
//         },
//         text: {
//             text: '设备', // 默认文本，会被覆盖
//             fontSize: 12,
//             fill: '#262626',
//             refX: 0.5,
//             refY: '100%',
//             y: -10,
//             textAnchor: 'middle'
//         },
//     },
//     ports: { ...ports },
// }, true);


// 注册自定义节点
Graph.registerNode('device-node', {
    inherit: 'rect',
    markup: [
        { tagName: 'rect', selector: 'body' },
        { tagName: 'image', selector: 'image' },
        { tagName: 'text', selector: 'text' },
        { tagName: 'text', selector: 'params' }
    ],
    attrs: {
        body: {
            stroke: '#5F95FF',
            strokeWidth: 1,
            fill: '#EFF4FF',
            rx: 6,
            ry: 6
        },
        // image: {
        //   'xlink:href': '', // 初始留空，动态设置
        //   width: 40,
        //   height: 40,
        //   x: 10,
        //   y: 10
        // },

        image: {
            'xlink:href': '',
            width: 40,
            height: 40,
            refX: '50%',  // 横向参考点为节点中心
            refY: '50%',  // 纵向参考点为节点中心
            x: -20,       // 向左偏移图片宽度的一半（40/2）
            y: -40        // 向上偏移图片高度的一半（40/2）
        },


        text: {
            text: '设备',
            fontSize: 13,
            fill: '#262626',
            // refX: 0.5,
            // refY: '100%',
            // y: -10,

            // refX: '50%',  // 横向参考点为节点中心
            // refY: '50%',  // 纵向参考点为节点中心
            // x: -20,       // 向左偏移图片宽度的一半（40/2）
            // y: -20,

            refY: '65%',

            textAnchor: 'middle',

            alignmentBaseline: 'middle',

            // textAnchor: 'middle'
        },
        params: {
            // text: '',
            fontSize: 12,
            // fill: '#666',
            // refX: 0.5,
            // refY: '100%',
            // y: 5,
            // textAnchor: 'middle',
            refX: '50%',  // 横向参考点为节点中心

            refY: '80%',
            textAnchor: 'middle',
            alignmentBaseline: 'middle',

            text: ''



        },


        deviceNo: '',
        data_res: []
        ,
    },
    ports: { ...ports },
}, true);


// 创建设备节点
// const createDeviceNode = (graph, item, position) => {
//     return graph.createNode({
//         shape: 'device-node',
//         width: 100,
//         height: 80,
//         x: position.x,
//         y: position.y,
//         attrs: {
//             text: { text: item.label },
//             // 可以根据不同类型设置不同图片
//             image: {
//                 'xlink:href': DEFAULT_IMAGE,
//                 width: 40,
//                 height: 40
//             }
//         },
//         data: { // 自定义数据
//             type: item.type,
//             label: item.label
//         }
//     });
// };


// 创建设备节点（优化版）
let createDeviceNode = (graph, item, position) => {
    let params = {};
    let paramsConfig = deviceParamsConfig[item.type] || [];
    paramsConfig.forEach(param => {
        params[param.key] = param.defaultValue;
    });

    let node = graph.createNode({
        shape: 'device-node',
        width: 120,
        height: 100,
        x: position.x,
        y: position.y,
        attrs: {
            image: {
                'xlink:href': type_icon_map[item.type], // 使用本地图标
                // width: 40,
                // height: 40,
                // x: 40,
                // y: 15
            },
            text: { text: item.label, },
            params: {
                text: paramsConfig.map(p => `${p.label}: ${params[p.key]}${p.unit}`).join('\n')
            },
            deviceNo: '',
            data_res: []
        },
        data: {
            type: item.type,
            label: item.label,
            params: params,

            deviceNo: '',
            data_res: [],

            deviceNo: '', // 初始为空
            deviceModel: null,
            selectedParam: []
        }
    });

    // 添加悬停交互
    node.on('mouseenter', () => {
        node.attr('body/stroke', '#1890ff');
        node.attr('body/strokeWidth', 2);
    });
    node.on('mouseleave', () => {
        node.attr('body/stroke', '#5F95FF');
        node.attr('body/strokeWidth', 1);
    });

    return node;
};



// 注册自定义连线
Graph.registerEdge('device-connection', {
    inherit: 'edge',
    attrs: {
        line: {
            stroke: '#1890ff',
            strokeWidth: 2,
            targetMarker: null,
            // targetMarker: {
            //     name: 'block',
            //     width: 12,
            //     height: 8,
            // },
        },
    },
    zIndex: 0,
}, true);

// 拖拽开始
// const handleDragStart = (e, item) => {
//     draggedItem.value = item;
//     e.dataTransfer.setData('text/plain', item.label);
//     e.dataTransfer.effectAllowed = 'copy';
// };


// 拖拽逻辑（优化版）
let handleDragStart = (e, item) => {
    draggedItem.value = item;

    // 创建拖拽预览
    let dragImage = new Image();
    dragImage.src = type_icon_map[item.type];
    dragImage.width = 50;
    dragImage.height = 50;

    // 创建克隆元素
    let cloneElement = e.target.cloneNode(true);
    cloneElement.style.position = 'absolute';
    cloneElement.style.pointerEvents = 'none';
    cloneElement.style.opacity = '0.7';
    document.body.appendChild(cloneElement);

    setTimeout(() => {
        e.dataTransfer.setDragImage(dragImage, 25, 25);
        e.dataTransfer.effectAllowed = 'copy';
    }, 0);

    // 清理克隆元素
    let dragEndHandler = () => {
        document.body.removeChild(cloneElement);
        e.target.removeEventListener('dragend', dragEndHandler);
    };
    e.target.addEventListener('dragend', dragEndHandler);
};



let initConnection = () => {
    let arrowCursor = document.createElement('div');
    arrowCursor.style.position = 'absolute';
    arrowCursor.style.width = '20px';
    arrowCursor.style.height = '20px';
    arrowCursor.style.backgroundImage = 'url("")';
    arrowCursor.style.backgroundSize = 'contain';
    arrowCursor.style.pointerEvents = 'none';
    arrowCursor.style.zIndex = '1000';
    arrowCursor.style.display = 'none';
    document.body.appendChild(arrowCursor);

    let handleMouseMove = (e) => {
        if (connectingState.isConnecting) {
            arrowCursor.style.display = 'block';
            arrowCursor.style.left = `${e.clientX + 10}px`;
            arrowCursor.style.top = `${e.clientY + 10}px`;

            if (connectingState.edge) {
                let point = graph.value.clientToLocal(e.clientX, e.clientY);
                connectingState.edge.setTarget(point);
            }
        }
    };

    let handleMouseDown = (e) => {
        if (e.button === 2 && !connectingState.isConnecting) {
            let node = getNodeAtPoint(e.clientX, e.clientY);
            if (node) {
                startConnection(node, e.clientX, e.clientY);
            }
        }
    };

    let handleMouseUp = (e) => {
        if (e.button === 2 && connectingState.isConnecting) {
            let node = getNodeAtPoint(e.clientX, e.clientY);
            if (node && node.id !== connectingState.sourceNode.id) {
                completeConnection(node);
            } else {
                cancelConnection();
            }
        }
    };

    window.addEventListener('mousemove', handleMouseMove);
    window.addEventListener('mousedown', handleMouseDown);
    window.addEventListener('mouseup', handleMouseUp);

    onBeforeUnmount(() => {
        window.removeEventListener('mousemove', handleMouseMove);
        window.removeEventListener('mousedown', handleMouseDown);
        window.removeEventListener('mouseup', handleMouseUp);
        document.body.removeChild(arrowCursor);
    });
};

// 开始创建连线
let startConnection = (sourceNode, clientX, clientY) => {
    connectingState.isConnecting = true;
    connectingState.sourceNode = sourceNode;


    console.log( "startConnection--开始连线",sourceNode)

    if(sourceNode.data.deviceNo==''){
        Modal.error({
            content: '连线之前必须先绑定设备'
        })
        return;

    }
    let point = graph.value.clientToLocal(clientX, clientY);
    connectingState.edge = graph.value.addEdge({
        shape: 'device-connection', // 直接使用注册的形状
        source: { cell: sourceNode.id },
        target: point,
        attrs: {
            line: {
                stroke: '#1890ff',
                strokeWidth: 2,
                targetMarker: null,
                // targetMarker: {
                //     name: 'block',
                //     width: 12,
                //     height: 8,
                // },
                strokeDasharray: '5 5',
            }
        },
        zIndex: 0,
    });
};



// const addCurrentAnimation = (edge, direction) => {
//     const edgeView = edge.findView(graph.value);
//     if (!edgeView) return;

//     // 获取路径数据
//     const path = edgeView.getPath();
//     if (!path) return;

//     // 创建电流路径
//     const currentPath = new Dom.vector('path')
//         .attr({
//             d: path.serialize(),
//             fill: 'none',
//             stroke: '#ffeb3b',
//             'stroke-width': 3,
//             'stroke-dasharray': '5, 10',
//             'class': `current-flow-${direction}-${edge.id}`,
//             'pointer-events': 'none'
//         })
//         .node;

//     // 添加到SVG容器
//     const container = edgeView.container;
//     container.appendChild(currentPath);

//     // 计算路径长度（X6 2.18.1兼容方式）
//     const tempPath = document.createElementNS('http://www.w3.org/2000/svg', 'path');
//     tempPath.setAttribute('d', path.serialize());
//     const length = tempPath.getTotalLength();

//     // 添加动画
//     const style = document.createElement('style');
//     style.textContent = `
//     @keyframes current-flow-right-${edge.id} {
//       0% { stroke-dashoffset: ${length}; }
//       100% { stroke-dashoffset: 0; }
//     }
//     @keyframes current-flow-left-${edge.id} {
//       0% { stroke-dashoffset: 0; }
//       100% { stroke-dashoffset: ${length}; }
//     }
//     .current-flow-right-${edge.id} {
//       animation: current-flow-right-${edge.id} 1.5s linear infinite;
//     }
//     .current-flow-left-${edge.id} {
//       animation: current-flow-left-${edge.id} 1.5s linear infinite;
//     }
//   `;
//     document.head.appendChild(style);
// };


// 新增：电流方向配置变量
const currentDirection = ref('auto'); // auto | right | left


const addCurrentAnimation = (edge) => {
    // 确保图形实例存在
    if (!graph.value) return;

    // 获取边的视图
    const edgeView = edge.findView(graph.value);
    if (!edgeView || !edgeView.container) return;

    // 获取路径元素
    const pathElement = edgeView.container.querySelector('path');
    if (!pathElement) return;

    // 获取路径数据
    const pathData = pathElement.getAttribute('d');
    if (!pathData) return;

    // 计算路径长度
    const tempPath = document.createElementNS('http://www.w3.org/2000/svg', 'path');
    tempPath.setAttribute('d', pathData);
    const length = tempPath.getTotalLength();

    // 创建电流路径
    const currentPath = document.createElementNS('http://www.w3.org/2000/svg', 'path');
    currentPath.setAttribute('d', pathData);
    currentPath.setAttribute('fill', 'none');
    currentPath.setAttribute('stroke', 'red');
    currentPath.setAttribute('stroke-width', '3');
    currentPath.setAttribute('stroke-dasharray', '5, 10');
    currentPath.setAttribute('class', `current-flow-${edge.id}`);
    currentPath.style.pointerEvents = 'none';

    // 添加到SVG容器
    edgeView.container.appendChild(currentPath);

    // 存储电流路径引用，用于后续更新
    edge.data.currentPath = currentPath;

    // 添加动画
    const style = document.createElement('style');
    style.textContent = `
    @keyframes current-flow-${edge.id} {
      0% { stroke-dashoffset: ${length}; }
      100% { stroke-dashoffset: 0; }
    }
    .current-flow-${edge.id} {
      animation: current-flow-${edge.id} 1.5s linear infinite;
    }
  `;
    document.head.appendChild(style);

    // 存储动画样式引用，用于后续清理
    edge.data.currentStyle = style;
};



// 更新电流路径位置
const updateCurrentPath = (edge) => {
    if (!edge.data.currentPath) return;

    // 获取边的视图
    const edgeView = edge.findView(graph.value);
    if (!edgeView || !edgeView.container) return;

    // 获取路径元素
    const pathElement = edgeView.container.querySelector('path');
    if (!pathElement) return;

    // 获取更新后的路径数据
    const pathData = pathElement.getAttribute('d');
    if (!pathData) return;

    // 更新电流路径
    edge.data.currentPath.setAttribute('d', pathData);

    // 重新计算路径长度
    const tempPath = document.createElementNS('http://www.w3.org/2000/svg', 'path');
    tempPath.setAttribute('d', pathData);
    const length = tempPath.getTotalLength();

    // 更新动画
    const style = edge.data.currentStyle;
    if (style) {
        style.textContent = `
      @keyframes current-flow-${edge.id} {
        0% { stroke-dashoffset: ${length}; }
        100% { stroke-dashoffset: 0; }
      }
      .current-flow-${edge.id} {
        animation: current-flow-${edge.id} 1.5s linear infinite;
      }
    `;
    }
};


// 完成连线
let completeConnection = (targetNode) => {
    if (connectingState.edge) {
        // 移除临时连线
        graph.value.removeCell(connectingState.edge);



        // 获取源节点和目标节点位置
        const sourcePos = connectingState.sourceNode.position();
        const targetPos = targetNode.position();
        const direction = sourcePos.x < targetPos.x ? 'right' : 'left';


        console.log("connectingState.sourceNode.data", connectingState.sourceNode.data)
        console.log(" targetNode.data", targetNode.data)


        if(targetNode.data.deviceNo==''){
        Modal.error({
            content: '连线之前必须先绑定设备'
        })
        return;

    }

        // 创建正式连线
        let edge = graph.value.addEdge({
            shape: 'device-connection',
            source: { cell: connectingState.sourceNode.id },
            target: { cell: targetNode.id },
            attrs: {
                line: {
                    stroke: '#1890ff',
                    strokeWidth: 2,
                    targetMarker: null,
                    // targetMarker: {
                    //     name: 'block',
                    //     width: 12,
                    //     height: 8,
                    // },
                }
            },


            data: {
                type: 'connection',
                from: connectingState.sourceNode.data.label,
                to: targetNode.data.label,
                deviceno_from: connectingState.sourceNode.data.deviceNo || '',
                deviceno_to: targetNode.data.deviceNo || '',
                createdAt: new Date().toISOString(),

                direction: currentDirection.value
            },
            zIndex: 0,
        });


        // setTimeout(() => {
        //     if (edge && edge.findView(graph.value)) {
        //         // const sourcePos = connectingState.sourceNode.getPosition();
        //         // const targetPos = targetNode.getPosition();
        //         // // const direction = sourcePos.x < targetPos.x ? 'right' : 'left';
        //         const direction = 'left';
        //         addCurrentAnimation(edge, direction);
        //     }
        // }, 100);

        // 添加电流动画
        // 添加电流动画
        setTimeout(() => {
            if (edge && graph.value) {
                addCurrentAnimation(edge, direction);
            }
        }, 100);

    }

    resetConnectionState();
};



// 监听节点移动事件
const setupNodeMoveListener = () => {
    if (!graph.value) return;

    graph.value.on('node:change:position', ({ node }) => {
        // 获取与该节点相连的所有边
        const edges = graph.value.getConnectedEdges(node);

        // 更新每条边的电流路径
        edges.forEach(edge => {
            updateCurrentPath(edge);
        });
    });
};

// 清理电流动画资源
const cleanupCurrentAnimation = (edge) => {

    if (!edge.data) {
        return;
    }
    if (edge.data.currentStyle && edge.data.currentStyle.parentNode) {
        edge.data.currentStyle.parentNode.removeChild(edge.data.currentStyle);
    }

    if (edge.data.currentPath && edge.data.currentPath.parentNode) {
        edge.data.currentPath.parentNode.removeChild(edge.data.currentPath);
    }
};


// 获取鼠标位置的节点（兼容X6 2.18.1版本）
// let getNodeAtPoint = (clientX, clientY) => {
//   if (!graph.value) return null;

//   let point = graph.value.clientToLocal(clientX, clientY);
//   let nodes = graph.value.getNodes();

//   // 使用getBBox判断节点是否包含点
//   for (let i = nodes.length - 1; i >= 0; i--) {
//     let node = nodes[i];
//     let bbox = node.getBBox();
//     if (bbox.containsPoint(point)) {
//       return node;
//     }
//   }

//   return null;
// };


// 获取鼠标位置的节点（兼容X6 2.18.1版本）
let getNodeAtPoint = (clientX, clientY) => {
    if (!graph.value) return null;

    let point = graph.value.clientToLocal(clientX, clientY);
    let nodes = graph.value.getNodes();

    // 使用getBBox判断节点是否包含点
    for (let i = nodes.length - 1; i >= 0; i--) {
        let node = nodes[i];
        let bbox = node.getBBox();
        if (bbox.containsPoint(point)) {
            return node;
        }
    }

    return null;
};

// 取消连线
let cancelConnection = () => {
    if (connectingState.edge) {
        graph.value.removeCell(connectingState.edge);
    }
    resetConnectionState();
};

// 重置连线状态
let resetConnectionState = () => {
    connectingState.isConnecting = false;
    connectingState.sourceNode = null;
    connectingState.edge = null;
    document.querySelectorAll('.arrow-cursor').forEach(el => el.style.display = 'none');
};

// 拖拽经过画布
const handleDragOver = (e) => {
    e.preventDefault();
    e.dataTransfer.dropEffect = 'copy';
};

// 拖拽放置
const handleDrop = (e) => {
    e.preventDefault();
    if (!draggedItem.value || !graph.value) return;

    // 获取鼠标在画布中的位置
    const rect = container.value.getBoundingClientRect();
    const x = e.clientX - rect.left;
    const y = e.clientY - rect.top;

    // 创建节点
    const node = createDeviceNode(graph.value, draggedItem.value, { x, y });
    graph.value.addNode(node);

    draggedItem.value = null;
};



function export_svg() {
    setTimeout(() => {

        //  let svg= document.getElementsByClassName('x6-graph-svg')[0];

        //  window.sessionStorage.setItem("svg_ele",svg.outerHTML)

        console.log(" graph.value.toJSON()", graph.value.toJSON())
        graph.value.toJSON()

        window.localStorage.setItem("json_ex", JSON.stringify(graph.value.toJSON()))
        // graph.value.use(new Export());
        // graph.value.exportSVG("exp")



    }, 3000)
}

onMounted(() => {
    // 初始化画布
    graph.value = new Graph({
        panning: { enabled: true, modifiers: 'space', eventTypes: "leftMouseDown" },
        scaling: { min: 0.05, max: 1 },
        mousewheel: {
            enabled: true,
            modifiers: ['ctrl', 'meta'],
            guard: (e) => !e.altKey
        },
        grid: {
            size: 10,
            visible: true,
            args: { color: '#a0a0a0', thickness: 1 }
        },
        container: container.value,
        connecting: { anchor: 'orth' },
    });


    // graph.value.

    // 添加一个示例节点
    // const sampleNode = createDeviceNode(graph.value, { label: '示例设备', type: 'sample' }, { x: 100, y: 100 });
    // graph.value.addNode(sampleNode);


    // 设置节点移动监听
    setupNodeMoveListener();

    initConnection();


    // 监听边被删除事件
    graph.value.on('edge:removed', ({ edge }) => {
        cleanupCurrentAnimation(edge);
    });


    graph.value.on('node:click', ({ node }) => {
        selectedDevice.value = node;
        showEditModal(node);
    });

});

// 在组件卸载前清理所有电流动画
onBeforeUnmount(() => {
    if (graph.value) {
        // 清理所有边的电流动画
        const edges = graph.value.getEdges();
        edges.forEach(edge => {
            cleanupCurrentAnimation(edge);
        });
    }
});


// 模态框取消
let handleModalCancel = () => {
    modalVisible.value = false;
};

// 显示编辑模态框
let showEditModal = (node) => {


    let device_type = node.data.type;

    console.log("device_type", device_type);

    console.log("device_type", device_type);

    console.log("node", node)

    node.data.data_res



    // deviceParams.value = deviceParamsConfig[node.data.type] || [];

    // Object.keys(deviceForm.value).forEach(key => delete deviceForm.value[key]);

    // deviceParams.value.forEach(param => {
    //   deviceForm.value[param.key] = node.data.params[param.key];
    // });

    modalVisible.value = true;
};


// 参数配置映射
let paramConfigMap = {
    27: [
        { label: "功率", tagcode: "P", unit: "kW", defaultValue: '' },
        { label: "无功功率", tagcode: "Q", unit: "kW", defaultValue: '' }
    ],
    1: [
        { label: "电压", tagcode: "U", unit: "V", defaultValue: '' },
        { label: "电流", tagcode: "I", unit: "A", defaultValue: '' }
    ]
};

function change_device(a, b) {
    console.log(a, b)
}

// 设备选项列表
let device_list = ref([
    { label: "PCS1", deviceNo: '20210002', deviceModel: 27, },
    { label: "PCS2", deviceNo: '20210003', deviceModel: 27 },
    { label: "电表", deviceNo: '20210004', deviceModel: 1 }
]);


let tagcode_ptions = ref([]);



// let deviceForm = ref({
//   deviceNo: '',
//   deviceTagcode: [
//     {
//      label:"功率"
//       tagcode: "P",
//       unit: 'kW',
//       defaultValue: ''
//     }
//   ]
// });
function change_tagcode(a, b) {
    console.log(a, b);

    deviceForm.value.deviceTagcode = b;
}

watch(() => deviceForm.value.deviceNo, (a) => {

    console.log("watch", a);

    if (a) {
        let device_modal = (device_list.value.filter((item, key) => item.deviceNo == a)[0]).deviceModel;
        tagcode_ptions.value = paramConfigMap[device_modal]
    }


});


// 修改保存处理方法
let handleModalOk = () => {
    if (!selectedDevice.value) return;

    console.log("selectedDevice", selectedDevice.value);

    console.log("deviceForm", deviceForm.value);

    // 更新设备数据
    let selectedDeviceInfo = device_list.value.find(
        opt => opt.deviceNo === deviceForm.value.deviceNo
    );

    selectedDevice.value.data = {
        ...selectedDevice.value.data,
        deviceNo: deviceForm.value.deviceNo,

        data_res: {
            ...deviceForm.value,
            // 确保参数列表包含 tagcode
            deviceTagcode: deviceForm.value.deviceTagcode.map(t => ({
                ...t,
                tagcode: t.tagcode // 确保属性名正确
            }))
        }

        // deviceModel: selectedDeviceInfo?.deviceModel,
        // selectedParam: deviceForm.value.selectedParam,
        // data_res: deviceForm.value
    };
    updateNodeParamsDisplay(selectedDevice.value, deviceForm.value);
    modalVisible.value = false;
};

let updateNodeParamsDisplay = (node, data_res) => {

    console.log("data_res", data_res)
    // 生成带占位符的参数文本
    let tagcode_text = data_res.deviceTagcode
        .map(item => {
            // 当 deviceNo 存在时生成 {{deviceNo.tagcode}} 格式
            //   const placeholder = data_res.deviceNo
            //     ? `{{de${data_res.deviceNo}.${item.tagcode}}}`
            //     : '{{未绑定设备}}'; // 未绑定时的默认显示

            let placeholder = ''
            return `${item.label}:${placeholder}${item.unit}`
        })
        .join('\n');

    // 更新节点显示
    node.attr('params/text', tagcode_text);
    node.attr('text/text', data_res.deviceName);

    node.attr('data/data_res', data_res)

    node.attr('params/deviceNo', data_res.deviceNo);
    node.attr('params/deviceTagcode', data_res.deviceTagcode);
};




</script>

<style scoped>
.xpage {
    height: 100vh;
    display: flex;
}

.my_container {
    flex: 1;
    height: 100%;
    border: 1px solid #d9d9d9;
    background: #f5f5f5;
}

.left_obj {
    background-color: #fff;
    width: 200px;
    padding: 10px;
    border-right: 1px solid #d9d9d9;
}

.draggable-item {
    background-color: #1890ff;
    color: white;
    text-align: center;
    line-height: 40px;
    border-radius: 4px;
    cursor: move;
    margin-bottom: 10px;
    user-select: none;
    transition: all 0.3s;
}

.draggable-item:hover {
    background-color: #40a9ff;
    transform: translateX(5px);
}
</style>


<style scoped>
/* 原有样式保持不变 */

/* 添加电流动画样式 */
@keyframes current-flow {
    0% {
        stroke-dashoffset: var(--path-length);
    }

    100% {
        stroke-dashoffset: 0;
    }
}

.current-flow {
    animation: current-flow 1.5s linear infinite;
}
</style>